#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
用户路由

这个模块包含用户管理相关的 API 端点：
1. 获取用户列表
2. 获取用户详情
3. 更新用户信息
4. 删除用户
5. 用户搜索
6. 用户统计

支持分页、搜索、排序等功能
包含权限控制和数据验证

作者: FastAPI 学习项目
创建时间: 2024
"""

from typing import Any, List, Optional
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session
from pydantic import BaseModel
from loguru import logger

from app.database.connection import get_db
from app.database.crud import crud_user
from app.models.user import User, UserUpdate, UserResponse
from app.utils.security import get_current_active_user, get_current_superuser
from app.utils.helpers import create_pagination_response
from config import settings

# 创建路由器
router = APIRouter()


# Pydantic 模型
class UserListResponse(BaseModel):
    """
    用户列表响应模型
    """
    users: List[UserResponse]
    total: int
    page: int
    size: int
    pages: int


class UserSearchResponse(BaseModel):
    """
    用户搜索响应模型
    """
    users: List[UserResponse]
    total: int
    query: str
    page: int
    size: int


class UserStatsResponse(BaseModel):
    """
    用户统计响应模型
    """
    total_users: int
    active_users: int
    inactive_users: int
    superusers: int
    recent_registrations: int


class MessageResponse(BaseModel):
    """
    消息响应模型
    """
    message: str


@router.get(
    "/",
    response_model=UserListResponse,
    summary="获取用户列表",
    description="获取所有用户的分页列表（需要超级用户权限）"
)
async def get_users(
    page: int = Query(1, ge=1, description="页码"),
    size: int = Query(10, ge=1, le=100, description="每页数量"),
    is_active: Optional[bool] = Query(None, description="筛选活跃用户"),
    is_superuser: Optional[bool] = Query(None, description="筛选超级用户"),
    sort_by: str = Query("created_at", description="排序字段"),
    sort_order: str = Query("desc", regex="^(asc|desc)$", description="排序方向"),
    current_user: User = Depends(get_current_superuser),
    db: Session = Depends(get_db)
) -> Any:
    """
    获取用户列表
    
    返回分页的用户列表，支持筛选和排序。
    只有超级用户可以访问此端点。
    
    Args:
        page: 页码（从1开始）
        size: 每页数量（1-100）
        is_active: 筛选活跃用户
        is_superuser: 筛选超级用户
        sort_by: 排序字段
        sort_order: 排序方向（asc/desc）
        current_user: 当前登录的超级用户
        db: 数据库会话
        
    Returns:
        UserListResponse: 分页的用户列表
        
    Raises:
        HTTPException: 当权限不足时抛出 403 错误
    """
    try:
        logger.info(f"获取用户列表请求: page={page}, size={size}, 请求者={current_user.username}")
        
        # 计算偏移量
        skip = (page - 1) * size
        
        # 构建筛选条件
        filters = {}
        if is_active is not None:
            filters['is_active'] = is_active
        if is_superuser is not None:
            filters['is_superuser'] = is_superuser
        
        # 获取用户列表
        users = crud_user.get_multi(
            db,
            skip=skip,
            limit=size,
            filters=filters,
            sort_by=sort_by,
            sort_order=sort_order
        )
        
        # 获取总数
        total = crud_user.count(db, filters=filters)
        
        # 计算总页数
        pages = (total + size - 1) // size
        
        logger.info(f"用户列表获取成功: 返回 {len(users)} 个用户，总计 {total} 个")
        
        return {
            "users": users,
            "total": total,
            "page": page,
            "size": size,
            "pages": pages
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取用户列表异常: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取用户列表失败"
        )


@router.get(
    "/me",
    response_model=UserResponse,
    summary="获取当前用户信息",
    description="获取当前登录用户的详细信息"
)
async def get_current_user_profile(
    current_user: User = Depends(get_current_active_user)
) -> Any:
    """
    获取当前用户信息
    
    返回当前登录用户的详细信息。
    
    Args:
        current_user: 当前登录用户
        
    Returns:
        UserResponse: 用户详细信息
    """
    try:
        logger.info(f"获取当前用户信息: {current_user.username}")
        return current_user
        
    except Exception as e:
        logger.error(f"获取当前用户信息异常: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取用户信息失败"
        )


@router.get(
    "/{user_id}",
    response_model=UserResponse,
    summary="获取用户详情",
    description="根据用户ID获取用户详细信息"
)
async def get_user(
    user_id: int,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
) -> Any:
    """
    获取用户详情
    
    根据用户ID获取用户的详细信息。
    普通用户只能查看自己的信息，超级用户可以查看任何用户的信息。
    
    Args:
        user_id: 用户ID
        current_user: 当前登录用户
        db: 数据库会话
        
    Returns:
        UserResponse: 用户详细信息
        
    Raises:
        HTTPException: 当用户不存在或权限不足时抛出相应错误
    """
    try:
        logger.info(f"获取用户详情请求: user_id={user_id}, 请求者={current_user.username}")
        
        # 获取目标用户
        user = crud_user.get(db, id=user_id)
        if not user:
            logger.warning(f"用户不存在: {user_id}")
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="用户不存在"
            )
        
        # 权限检查：用户只能查看自己的信息，除非是超级用户
        if user_id != current_user.id and not current_user.is_superuser:
            logger.warning(f"权限不足: {current_user.username} 尝试查看用户 {user_id}")
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="权限不足"
            )
        
        logger.info(f"用户详情获取成功: {user.username}")
        return user
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取用户详情异常: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取用户详情失败"
        )


@router.put(
    "/me",
    response_model=UserResponse,
    summary="更新当前用户信息",
    description="更新当前登录用户的信息"
)
async def update_current_user(
    user_update: UserUpdate,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
) -> Any:
    """
    更新当前用户信息
    
    允许用户更新自己的个人信息。
    
    Args:
        user_update: 用户更新数据
        current_user: 当前登录用户
        db: 数据库会话
        
    Returns:
        UserResponse: 更新后的用户信息
        
    Raises:
        HTTPException: 当邮箱已存在时抛出 400 错误
        
    Example:
        ```json
        {
            "full_name": "Updated Name",
            "email": "newemail@example.com",
            "bio": "Updated bio"
        }
        ```
    """
    try:
        logger.info(f"更新用户信息请求: {current_user.username}")
        
        # 如果更新邮箱，检查邮箱是否已被其他用户使用
        if user_update.email and user_update.email != current_user.email:
            existing_user = crud_user.get_by_email(db, email=user_update.email)
            if existing_user and existing_user.id != current_user.id:
                logger.warning(f"邮箱已存在: {user_update.email}")
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="邮箱地址已被使用"
                )
        
        # 更新用户信息
        updated_user = crud_user.update(db, db_obj=current_user, obj_in=user_update)
        logger.info(f"用户信息更新成功: {updated_user.username}")
        
        return updated_user
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新用户信息异常: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="更新用户信息失败"
        )


@router.put(
    "/{user_id}",
    response_model=UserResponse,
    summary="更新用户信息",
    description="更新指定用户的信息（需要超级用户权限）"
)
async def update_user(
    user_id: int,
    user_update: UserUpdate,
    current_user: User = Depends(get_current_superuser),
    db: Session = Depends(get_db)
) -> Any:
    """
    更新用户信息
    
    允许超级用户更新任何用户的信息。
    
    Args:
        user_id: 要更新的用户ID
        user_update: 用户更新数据
        current_user: 当前登录的超级用户
        db: 数据库会话
        
    Returns:
        UserResponse: 更新后的用户信息
        
    Raises:
        HTTPException: 当用户不存在或邮箱已存在时抛出相应错误
    """
    try:
        logger.info(f"更新用户信息请求: user_id={user_id}, 操作者={current_user.username}")
        
        # 获取目标用户
        user = crud_user.get(db, id=user_id)
        if not user:
            logger.warning(f"用户不存在: {user_id}")
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="用户不存在"
            )
        
        # 如果更新邮箱，检查邮箱是否已被其他用户使用
        if user_update.email and user_update.email != user.email:
            existing_user = crud_user.get_by_email(db, email=user_update.email)
            if existing_user and existing_user.id != user.id:
                logger.warning(f"邮箱已存在: {user_update.email}")
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="邮箱地址已被使用"
                )
        
        # 更新用户信息
        updated_user = crud_user.update(db, db_obj=user, obj_in=user_update)
        logger.info(f"用户信息更新成功: {updated_user.username} (操作者: {current_user.username})")
        
        return updated_user
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新用户信息异常: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="更新用户信息失败"
        )


@router.delete(
    "/{user_id}",
    response_model=MessageResponse,
    summary="删除用户",
    description="删除指定用户（需要超级用户权限）"
)
async def delete_user(
    user_id: int,
    current_user: User = Depends(get_current_superuser),
    db: Session = Depends(get_db)
) -> Any:
    """
    删除用户
    
    允许超级用户删除指定的用户。
    不能删除自己的账户。
    
    Args:
        user_id: 要删除的用户ID
        current_user: 当前登录的超级用户
        db: 数据库会话
        
    Returns:
        MessageResponse: 删除成功消息
        
    Raises:
        HTTPException: 当用户不存在或尝试删除自己时抛出相应错误
    """
    try:
        logger.info(f"删除用户请求: user_id={user_id}, 操作者={current_user.username}")
        
        # 不能删除自己
        if user_id == current_user.id:
            logger.warning(f"尝试删除自己的账户: {current_user.username}")
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="不能删除自己的账户"
            )
        
        # 获取目标用户
        user = crud_user.get(db, id=user_id)
        if not user:
            logger.warning(f"用户不存在: {user_id}")
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="用户不存在"
            )
        
        # 删除用户
        crud_user.remove(db, id=user_id)
        logger.info(f"用户删除成功: {user.username} (操作者: {current_user.username})")
        
        return {"message": f"用户 {user.username} 已被删除"}
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"删除用户异常: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="删除用户失败"
        )


@router.get(
    "/search/",
    response_model=UserSearchResponse,
    summary="搜索用户",
    description="根据关键词搜索用户（需要超级用户权限）"
)
async def search_users(
    q: str = Query(..., min_length=1, description="搜索关键词"),
    page: int = Query(1, ge=1, description="页码"),
    size: int = Query(10, ge=1, le=50, description="每页数量"),
    current_user: User = Depends(get_current_superuser),
    db: Session = Depends(get_db)
) -> Any:
    """
    搜索用户
    
    根据用户名、邮箱或全名搜索用户。
    只有超级用户可以访问此端点。
    
    Args:
        q: 搜索关键词
        page: 页码（从1开始）
        size: 每页数量（1-50）
        current_user: 当前登录的超级用户
        db: 数据库会话
        
    Returns:
        UserSearchResponse: 搜索结果
        
    Raises:
        HTTPException: 当权限不足时抛出 403 错误
    """
    try:
        logger.info(f"搜索用户请求: q='{q}', page={page}, size={size}, 请求者={current_user.username}")
        
        # 计算偏移量
        skip = (page - 1) * size
        
        # 搜索用户
        users, total = crud_user.search(
            db,
            query=q,
            skip=skip,
            limit=size
        )
        
        logger.info(f"用户搜索完成: 找到 {total} 个结果，返回 {len(users)} 个")
        
        return {
            "users": users,
            "total": total,
            "query": q,
            "page": page,
            "size": size
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"搜索用户异常: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="搜索用户失败"
        )


@router.get(
    "/stats/overview",
    response_model=UserStatsResponse,
    summary="获取用户统计",
    description="获取用户统计信息（需要超级用户权限）"
)
async def get_user_stats(
    current_user: User = Depends(get_current_superuser),
    db: Session = Depends(get_db)
) -> Any:
    """
    获取用户统计
    
    返回用户相关的统计信息，包括总用户数、活跃用户数等。
    只有超级用户可以访问此端点。
    
    Args:
        current_user: 当前登录的超级用户
        db: 数据库会话
        
    Returns:
        UserStatsResponse: 用户统计信息
        
    Raises:
        HTTPException: 当权限不足时抛出 403 错误
    """
    try:
        logger.info(f"获取用户统计请求: 请求者={current_user.username}")
        
        # 获取统计数据
        total_users = crud_user.count(db)
        active_users = crud_user.count(db, filters={'is_active': True})
        inactive_users = total_users - active_users
        superusers = crud_user.count(db, filters={'is_superuser': True})
        
        # 获取最近7天的注册数
        from datetime import datetime, timedelta
        seven_days_ago = datetime.utcnow() - timedelta(days=7)
        recent_registrations = crud_user.count_recent_registrations(db, since=seven_days_ago)
        
        stats = {
            "total_users": total_users,
            "active_users": active_users,
            "inactive_users": inactive_users,
            "superusers": superusers,
            "recent_registrations": recent_registrations
        }
        
        logger.info(f"用户统计获取成功: {stats}")
        
        return stats
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取用户统计异常: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取用户统计失败"
        )


@router.post(
    "/{user_id}/activate",
    response_model=MessageResponse,
    summary="激活用户",
    description="激活指定用户（需要超级用户权限）"
)
async def activate_user(
    user_id: int,
    current_user: User = Depends(get_current_superuser),
    db: Session = Depends(get_db)
) -> Any:
    """
    激活用户
    
    激活指定的用户账户。
    只有超级用户可以执行此操作。
    
    Args:
        user_id: 要激活的用户ID
        current_user: 当前登录的超级用户
        db: 数据库会话
        
    Returns:
        MessageResponse: 激活成功消息
        
    Raises:
        HTTPException: 当用户不存在时抛出 404 错误
    """
    try:
        logger.info(f"激活用户请求: user_id={user_id}, 操作者={current_user.username}")
        
        # 获取目标用户
        user = crud_user.get(db, id=user_id)
        if not user:
            logger.warning(f"用户不存在: {user_id}")
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="用户不存在"
            )
        
        # 激活用户
        if not user.is_active:
            user_update = UserUpdate(is_active=True)
            crud_user.update(db, db_obj=user, obj_in=user_update)
            logger.info(f"用户激活成功: {user.username} (操作者: {current_user.username})")
            return {"message": f"用户 {user.username} 已被激活"}
        else:
            logger.info(f"用户已经是激活状态: {user.username}")
            return {"message": f"用户 {user.username} 已经是激活状态"}
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"激活用户异常: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="激活用户失败"
        )


@router.post(
    "/{user_id}/deactivate",
    response_model=MessageResponse,
    summary="停用用户",
    description="停用指定用户（需要超级用户权限）"
)
async def deactivate_user(
    user_id: int,
    current_user: User = Depends(get_current_superuser),
    db: Session = Depends(get_db)
) -> Any:
    """
    停用用户
    
    停用指定的用户账户。
    不能停用自己的账户。
    只有超级用户可以执行此操作。
    
    Args:
        user_id: 要停用的用户ID
        current_user: 当前登录的超级用户
        db: 数据库会话
        
    Returns:
        MessageResponse: 停用成功消息
        
    Raises:
        HTTPException: 当用户不存在或尝试停用自己时抛出相应错误
    """
    try:
        logger.info(f"停用用户请求: user_id={user_id}, 操作者={current_user.username}")
        
        # 不能停用自己
        if user_id == current_user.id:
            logger.warning(f"尝试停用自己的账户: {current_user.username}")
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="不能停用自己的账户"
            )
        
        # 获取目标用户
        user = crud_user.get(db, id=user_id)
        if not user:
            logger.warning(f"用户不存在: {user_id}")
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="用户不存在"
            )
        
        # 停用用户
        if user.is_active:
            user_update = UserUpdate(is_active=False)
            crud_user.update(db, db_obj=user, obj_in=user_update)
            logger.info(f"用户停用成功: {user.username} (操作者: {current_user.username})")
            return {"message": f"用户 {user.username} 已被停用"}
        else:
            logger.info(f"用户已经是停用状态: {user.username}")
            return {"message": f"用户 {user.username} 已经是停用状态"}
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"停用用户异常: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="停用用户失败"
        )